package com.bito.aiot.common.holder;

import com.esotericsoftware.reflectasm.MethodAccess;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author 小木
 * @date 2022/7/26
 * @description 反射缓存类-ReflectASM
 */
public class ReflectAsmManager {

    private static final ConcurrentMap<Class<?>, MethodAccess> LOCAL_CACHE = new ConcurrentHashMap<>();

    public static MethodAccess get(Class<?> clazz) {
        if (LOCAL_CACHE.containsKey(clazz)) {
            return LOCAL_CACHE.get(clazz);
        }

        MethodAccess methodAccess = MethodAccess.get(clazz);
        LOCAL_CACHE.putIfAbsent(clazz, methodAccess);
        return methodAccess;
    }

    /**
     * 将A对象[字段赋值]给B对象
     *
     * @param from A-对象
     * @param to   B-对象
     * @param <F>  A.范型
     * @param <T>  B.范型
     */
    public static <F, T> void copyProperties(F from, T to) {
        MethodAccess fromMethodAccess = get(from.getClass());
        MethodAccess toMethodAccess = get(to.getClass());
        Field[] fromDeclaredFields = from.getClass().getDeclaredFields();
        for (Field field : fromDeclaredFields) {
            String name = field.getName();
            try {
                Object value = fromMethodAccess.invoke(from, "get" + StringUtils.capitalize(name), null);
                toMethodAccess.invoke(to, "set" + StringUtils.capitalize(name), value);
            } catch (Exception e) {
                // 设置异常，可能会没有对应字段，忽略
            }
        }

    }


}
